package mall.kotlin.com.kotlinlearn.part

import org.junit.Test


val FINAL_HELLO_WORLD: String = "HelloWord"//val相当于java中final
const val FINAL_HELLO_WORLD2: String = "HelloWord"//const val相当于java中static final 编译期常量
var hello_world: String = "HelloWord"//var相当于java中的非final类型
val HELLO_WORLD = "HelloWord"//自动类型推导，不用写数据类型

private const val DEBUG = 1
private const val USER = 0

class 第二章程序结构 {
    val arrayOfChar: CharArray = charArrayOf('H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd')
    //常规写法
    fun sum(arg1: Int, arg2: Int): Int {
        return arg1 + arg2
    }

    //简洁写法
    fun sum1(arg1: Int, arg2: Int) = arg1 + arg2


    //lambda表达式写法   (Int, Int)->Int
    val sum3 = { arg1: Int, arg2: Int ->
        println("$arg1+$arg2 = ${arg1 + arg2}")
        arg1 + arg2
    }


    //变量接收函数值  (Int)->Long
    val int2Long = fun(x: Int): Long = x.toLong()


    @Test
    fun Test1() {
        //lambda表达式
//        println(int2Long(3))
//        sum3(1, 3)
//        sum3.invoke(1, 3)//invoke 运算符重载
//        arrayOfChar.forEach({ it -> println(it) })//遍历数组
//        arrayOfChar.forEach { element -> println(element) }//遍历数组
//        arrayOfChar.forEach(::println)//遍历数组
//        arrayOfChar.forEach {
//            if (it == 'o') return//相当于return  main函数
//            println(it)
//        }
//        arrayOfChar.forEach ForEach@{
//            if (it == 'o') return@ForEach//相当于跳出lambda表达式
//            println(it)
//        }
//
//        println("The end")
//
//        println(sum3)
//        println(int2Long)
//        println(::sum is (Int, Int) -> Int)


        //类成员
//        val 妹子 = 妹子("build/generated/source/apt/test", "build/generated/source/apt/test", "build/generated/source/apt/test")
//        妹子.唱歌("歌唱祖国")
//        妹子.跳舞("孔雀舞")
//
//
//        //基本运算符
//        val c1 = Complex(3.0, 4.0)
//        val c2 = Complex(2.0, 7.5)
//        println(c1 + c2)
//
//        if ( 'a' in arrayOfChar){
//
//        }
//
//        if (Book() on Desk()){
//
//        }

        //分支表达式
        //普通的就是 if else
//        if () {
//
//        } else {
//
//        }

        //if表达式
//        val mode = if (arrayOfChar.isNotEmpty() && arrayOfChar.get(0) == 'H') {
//            DEBUG//返回值
//        } else {
//            USER
//        }
        //循环语句
//        for (arg in arrayOfChar){
//            println(arg)
//        }
//
//        for (i in arrayOfChar.indices) {
//            print(arrayOfChar[i])
//        }
//
//        for ((index, value) in arrayOfChar.withIndex()) {
//            println("the element at $index is $value")
//        }
//        for (indexValue in arrayOfChar.withIndex()) {
//            println("the element at ${indexValue.index} is ${indexValue.value}")
//        }
//        val list = MyIntList()
//        list.add(1)
//        list.add(2)
//        list.add(3)
//        for (i in list){
//            println(i)
//        }

        //异常捕获
//        val args = intArrayOf(1, 2, 3)
//        val tryCatch = try {
//            args[0] / args[1]
//        } catch (e: Exception) {
//            e.printStackTrace()
//            0
//        }
//        println(tryCatch)


        fun hello(double: Double = 3.0, vararg ints: Int, string: String) {
            ints.forEach(::println)
            println(string)
        }
        fun sum(arg1: Int, arg2: Int) = arg1 + arg2
        val array = intArrayOf(1, 2, 3, 4, 5)
        //具名参数
        sum(arg1 = 1, arg2 = 3)
        //变长参数 作为参数的最后一个
        hello(3.0, 1, 2, 3, 4, 5, string = "hello")
        hello(3.0, *array, string = "hello")//*号展开变长参数的数组
        //默认参数  double 默认=3.0 可以不传
        hello(ints = *array, string = "hello")

    }


    //循环语句  自定义类的可以进行迭代
    class MyIterator(val iterator: Iterator<Int>) {
        operator fun next(): Int {
            return iterator.next()
        }

        operator fun hasNext(): Boolean {
            return iterator.hasNext()
        }
    }

    class MyIntList {
        private val list = ArrayList<Int>()
        fun add(int: Int) {
            list.add(int)
        }

        fun remove(int: Int) {
            list.remove(int)
        }

        operator fun iterator(): MyIterator {
            return MyIterator(list.iterator())
        }


    }


    class Book {
        infix fun on(nay: Any): Boolean {
            return false
        }
    }

    class Desk

    class X
    class A {
        // 默认实现了 get set方法  var和val都是public的
        var b = 0
        //            get() {
//                println("some one tries get b")
//                return field
//            }
//            set(value) {
//                println("some one tries set b")
//                field = value
//            }
        protected var a = 0
            protected get
            protected set
        lateinit var c: String//var 延迟初始化 使用的时候自己确保已经赋值
        lateinit var d: X
        val e: X by lazy { X() }//val使用 by lazy延迟初始化


    }

    class 妹子(性格: String, 长相: String, 声音: String) {
        fun 唱歌(歌名: String) {
            println("妹子正在唱歌，歌曲名-$歌名")
        }

        fun 跳舞(舞蹈名: String) {
            println("妹子正在跳舞，舞蹈名-$舞蹈名")
        }
    }

    //复数算法
    class Complex(var real: Double, var imaginary: Double) {
        operator fun plus(other: Complex): Complex {
            return Complex(real + other.real, imaginary + other.imaginary)
        }

        override fun toString(): String {
            return "${real} + ${imaginary}i"
        }
    }


    //表达式


    class Player {
        enum class State {
            IDLE, BUFFERING, PLAYERING, PAUSED
        }

        private val state = State.IDLE


        fun pause() {
            when (state) {
                Player.State.BUFFERING, Player.State.PLAYERING -> doPasuse()
            }


        }

        private fun doPasuse() {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }

    }
}

//小案例：命令行计数器开发
fun main(args: Array<String>) {
    while (true) {
        try {
            println("请输入算式例如： 3 + 4")
            val input = readLine() ?: break
            val splits = input.trim().split(" ")
            if(splits.size < 3){
                throw IllegalArgumentException("参数个数不对")
            }
            val arg1 = splits[0].toDouble()
            val op = splits[1]
            val arg2 = splits[2].toDouble()
            println("$arg1 $op $arg2 = ${Operator(op)(arg1, arg2)}")
        }catch (e: NumberFormatException){
            println("您确定输入的是数字吗？")
        }catch (e: IllegalArgumentException){
            println("您确定输入的是三个参数吗？或者您确定您的输入是用空格分隔的吗？")
        }catch (e: Exception){
            println("亲爱的用户，您的人品太差了，程序遇到了未知的异常，${e.message}")
        }

        println("再来一发?[Y]")
        val cmd = readLine()
        if (cmd == null || cmd.toLowerCase() != "y") {
            break
        }
    }
    println("感谢您使用我们的计算器。")
}

class Operator(op: String) {
    val opFun: (left: Double, right: Double) -> Double

    init {
        opFun = when (op) {
            "+" -> { l, r -> l + r }
            "-" -> { l, r -> l - r }
            "*" -> { l, r -> l * r }
            "/" -> { l, r -> l / r }
            "%" -> { l, r -> l % r }
            else -> {
                throw UnsupportedOperationException(op)
            }
        }
    }

    operator fun invoke(left: Double, right: Double): Double {
        return opFun(left, right)
    }

}

